﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x02000088 RID: 136
	public class Recoil : OffsetModifier
	{
		// Token: 0x06000506 RID: 1286 RVA: 0x0003262C File Offset: 0x0003082C
		public void Fire(float magnitude)
		{
			float num = magnitude * UnityEngine.Random.value * this.magnitudeRandom;
			this.magnitudeMlp = magnitude + num;
			this.randomRotation = Quaternion.Euler(this.rotationRandom * UnityEngine.Random.value);
			foreach (Recoil.RecoilOffset recoilOffset in this.offsets)
			{
				recoilOffset.Start();
			}
			if (Time.time < this.endTime)
			{
				this.blendWeight = 0f;
			}
			else
			{
				this.blendWeight = 1f;
			}
			Keyframe[] keys = this.recoilWeight.keys;
			this.length = keys[keys.Length - 1].time;
			this.endTime = Time.time + this.length;
		}

		// Token: 0x06000507 RID: 1287 RVA: 0x000326F4 File Offset: 0x000308F4
		public override void OnModifyOffset()
		{
			if (Time.time >= this.endTime)
			{
				return;
			}
			if (!this.initiated && this.ik != null)
			{
				this.initiated = true;
				IKSolverFullBodyBiped solver = this.ik.solver;
				solver.OnPostUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPostUpdate, new IKSolver.UpdateDelegate(this.AfterFBBIK));
			}
			this.blendTime = Mathf.Max(this.blendTime, 0f);
			if (this.blendTime > 0f)
			{
				this.blendWeight = Mathf.Min(this.blendWeight + Time.deltaTime * (1f / this.blendTime), 1f);
			}
			else
			{
				this.blendWeight = 1f;
			}
			float b = this.recoilWeight.Evaluate(this.length - (this.endTime - Time.time)) * this.magnitudeMlp;
			this.w = Mathf.Lerp(this.w, b, this.blendWeight);
			Quaternion quaternion = (!(this.aimIK != null)) ? this.ik.references.root.rotation : Quaternion.LookRotation(this.aimIK.solver.IKPosition - this.aimIK.solver.transform.position, this.ik.references.root.up);
			quaternion = this.randomRotation * quaternion;
			foreach (Recoil.RecoilOffset recoilOffset in this.offsets)
			{
				recoilOffset.Apply(this.ik.solver, quaternion, this.w, this.length, this.endTime - Time.time);
			}
			Quaternion lhs = Quaternion.Lerp(Quaternion.identity, Quaternion.Euler(this.randomRotation * this.primaryHand.rotation * this.handRotationOffset), this.w);
			this.handRotation = lhs * this.primaryHand.rotation;
			if (this.twoHanded)
			{
				Vector3 point = this.primaryHand.InverseTransformPoint(this.secondaryHand.position);
				this.secondaryHandRelativeRotation = Quaternion.Inverse(this.primaryHand.rotation) * this.secondaryHand.rotation;
				Vector3 a = this.primaryHand.position + this.primaryHandEffector.positionOffset;
				Vector3 a2 = a + this.handRotation * point;
				this.secondaryHandEffector.positionOffset += a2 - (this.secondaryHand.position + this.secondaryHandEffector.positionOffset);
			}
		}

		// Token: 0x06000508 RID: 1288 RVA: 0x000329D0 File Offset: 0x00030BD0
		public void AfterFBBIK()
		{
			if (Time.time >= this.endTime)
			{
				return;
			}
			this.primaryHand.rotation = this.handRotation;
			if (this.twoHanded)
			{
				this.secondaryHand.rotation = this.primaryHand.rotation * this.secondaryHandRelativeRotation;
			}
		}

		// Token: 0x17000072 RID: 114
		// (get) Token: 0x06000509 RID: 1289 RVA: 0x000052B5 File Offset: 0x000034B5
		public IKEffector primaryHandEffector
		{
			get
			{
				if (this.handedness == Recoil.Handedness.Right)
				{
					return this.ik.solver.rightHandEffector;
				}
				return this.ik.solver.leftHandEffector;
			}
		}

		// Token: 0x17000073 RID: 115
		// (get) Token: 0x0600050A RID: 1290 RVA: 0x000052E3 File Offset: 0x000034E3
		public IKEffector secondaryHandEffector
		{
			get
			{
				if (this.handedness == Recoil.Handedness.Right)
				{
					return this.ik.solver.leftHandEffector;
				}
				return this.ik.solver.rightHandEffector;
			}
		}

		// Token: 0x17000074 RID: 116
		// (get) Token: 0x0600050B RID: 1291 RVA: 0x00005311 File Offset: 0x00003511
		public Transform primaryHand
		{
			get
			{
				return this.primaryHandEffector.bone;
			}
		}

		// Token: 0x17000075 RID: 117
		// (get) Token: 0x0600050C RID: 1292 RVA: 0x0000531E File Offset: 0x0000351E
		public Transform secondaryHand
		{
			get
			{
				return this.secondaryHandEffector.bone;
			}
		}

		// Token: 0x0600050D RID: 1293 RVA: 0x00032A2C File Offset: 0x00030C2C
		public override void OnDestroy()
		{
			base.OnDestroy();
			if (this.ik != null && this.initiated)
			{
				IKSolverFullBodyBiped solver = this.ik.solver;
				solver.OnPostUpdate = (IKSolver.UpdateDelegate)Delegate.Remove(solver.OnPostUpdate, new IKSolver.UpdateDelegate(this.AfterFBBIK));
			}
		}

		// Token: 0x0400038D RID: 909
		[Tooltip("Reference to the AimIK component. Optional, only used to getting the aiming direction.")]
		public AimIK aimIK;

		// Token: 0x0400038E RID: 910
		[Tooltip("Which hand is holding the weapon?")]
		public Recoil.Handedness handedness;

		// Token: 0x0400038F RID: 911
		[Tooltip("Check for 2-handed weapons.")]
		public bool twoHanded = true;

		// Token: 0x04000390 RID: 912
		[Tooltip("Weight curve for the recoil offsets. Recoil procedure is as long as this curve.")]
		public AnimationCurve recoilWeight;

		// Token: 0x04000391 RID: 913
		[Tooltip("How much is the magnitude randomized each time Recoil is called?")]
		public float magnitudeRandom = 0.1f;

		// Token: 0x04000392 RID: 914
		[Tooltip("How much is the rotation randomized each time Recoil is called?")]
		public Vector3 rotationRandom;

		// Token: 0x04000393 RID: 915
		[Tooltip("Rotating the primary hand bone for the recoil (in local space).")]
		public Vector3 handRotationOffset;

		// Token: 0x04000394 RID: 916
		[Tooltip("Time of blending in another recoil when doing automatic fire.")]
		public float blendTime;

		// Token: 0x04000395 RID: 917
		[Space(10f)]
		[Tooltip("FBBIK effector position offsets for the recoil (in aiming direction space).")]
		public Recoil.RecoilOffset[] offsets;

		// Token: 0x04000396 RID: 918
		public float magnitudeMlp = 1f;

		// Token: 0x04000397 RID: 919
		public float endTime = -1f;

		// Token: 0x04000398 RID: 920
		public Quaternion handRotation;

		// Token: 0x04000399 RID: 921
		public Quaternion secondaryHandRelativeRotation;

		// Token: 0x0400039A RID: 922
		public Quaternion randomRotation;

		// Token: 0x0400039B RID: 923
		public float length = 1f;

		// Token: 0x0400039C RID: 924
		public bool initiated;

		// Token: 0x0400039D RID: 925
		public float blendWeight;

		// Token: 0x0400039E RID: 926
		public float w;

		// Token: 0x02000089 RID: 137
		[Serializable]
		public class RecoilOffset
		{
			// Token: 0x0600050F RID: 1295 RVA: 0x00005349 File Offset: 0x00003549
			public void Start()
			{
				if (this.additivity <= 0f)
				{
					return;
				}
				this.additiveOffset = Vector3.ClampMagnitude(this.lastOffset * this.additivity, this.maxAdditiveOffsetMag);
			}

			// Token: 0x06000510 RID: 1296 RVA: 0x00032A88 File Offset: 0x00030C88
			public void Apply(IKSolverFullBodyBiped solver, Quaternion rotation, float masterWeight, float length, float timeLeft)
			{
				this.additiveOffset = Vector3.Lerp(Vector3.zero, this.additiveOffset, timeLeft / length);
				this.lastOffset = rotation * (this.offset * masterWeight) + rotation * this.additiveOffset;
				foreach (Recoil.RecoilOffset.EffectorLink effectorLink in this.effectorLinks)
				{
					solver.GetEffector(effectorLink.effector).positionOffset += this.lastOffset * effectorLink.weight;
				}
			}

			// Token: 0x0400039F RID: 927
			[Tooltip("Offset vector for the associated effector when doing recoil.")]
			public Vector3 offset;

			// Token: 0x040003A0 RID: 928
			[Tooltip("When firing before the last recoil has faded, how much of the current recoil offset will be maintained?")]
			[Range(0f, 1f)]
			public float additivity = 1f;

			// Token: 0x040003A1 RID: 929
			[Tooltip("Max additive recoil for automatic fire.")]
			public float maxAdditiveOffsetMag = 0.2f;

			// Token: 0x040003A2 RID: 930
			[Tooltip("Linking this recoil offset to FBBIK effectors.")]
			public Recoil.RecoilOffset.EffectorLink[] effectorLinks;

			// Token: 0x040003A3 RID: 931
			public Vector3 additiveOffset;

			// Token: 0x040003A4 RID: 932
			public Vector3 lastOffset;

			// Token: 0x0200008A RID: 138
			[Serializable]
			public class EffectorLink
			{
				// Token: 0x040003A5 RID: 933
				[Tooltip("Type of the FBBIK effector to use")]
				public FullBodyBipedEffector effector;

				// Token: 0x040003A6 RID: 934
				[Tooltip("Weight of using this effector")]
				public float weight;
			}
		}

		// Token: 0x0200008B RID: 139
		[Serializable]
		public enum Handedness
		{
			// Token: 0x040003A8 RID: 936
			Right,
			// Token: 0x040003A9 RID: 937
			Left
		}
	}
}
